package com.duoqin.account.viewmodel;

import android.app.Application;
import android.arch.lifecycle.LiveData;
import android.arch.lifecycle.MutableLiveData;
import android.support.annotation.NonNull;
import android.util.Log;
import android.widget.Toast;

import com.duoqin.account.data.LoginRequest;
import com.duoqin.account.data.LoginResponse;
import com.duoqin.account.data.RefreshTokenResponse;
import com.duoqin.account.data.RegisterRequest;
import com.duoqin.account.data.remote.AccountApiInterface;
import com.duoqin.common.data.DefaultResponse;
import com.duoqin.common.data.remote.ApiClient;
import com.duoqin.syncassistant.viewmodel.BaseViewModel;
import com.duoqin.syncassistant.R;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.IOException;

import retrofit2.Call;
import retrofit2.Callback;
import retrofit2.Response;

public class LoginViewModel extends BaseViewModel {
    private static final String TAG = "duoqin_LoginViewModel";

    private AccountApiInterface mApiInterface;
    private MutableLiveData<DefaultResponse> mValidationCodeResponse;
    private MutableLiveData<LoginResponse> mRegisterResponse;
    private MutableLiveData<LoginResponse> mLoginResponse;
    private MutableLiveData<DefaultResponse> mLogoutResponse;
    private MutableLiveData<RefreshTokenResponse> mRefreshTokenResponse;

    public LoginViewModel(@NonNull Application application) {
        super(application);
        mApiInterface = ApiClient.getClient().create(AccountApiInterface.class);
    }

    public LiveData<DefaultResponse> validationCodeResponse() {
        if (mValidationCodeResponse == null) {
            mValidationCodeResponse = new MutableLiveData<>();
        }
        return mValidationCodeResponse;
    }

    public void requestValidationCode(String mobile) {
        Log.d(TAG, "requestValidationCode");
        final Call<DefaultResponse> call = mApiInterface.requestValidationCode(mobile);
        if (call != null) {
            call.enqueue(new Callback<DefaultResponse>() {
                @Override
                public void onResponse(Call<DefaultResponse> call,
                                       Response<DefaultResponse> response) {
                    Log.d(TAG, "onResponse = " + response);
                    if (response != null && mValidationCodeResponse != null) {
                        Log.d(TAG, "body " + response.body());
                        if (200 == response.code()) {
                            mValidationCodeResponse.setValue(response.body());
                        } else {
                            try {
                                String errorString = response.errorBody().string();
                                Log.w(TAG, "error " + errorString);
                                JSONObject jsonObject = new JSONObject(errorString);
                                DefaultResponse errorResponse = new DefaultResponse();
                                errorResponse.setCode(jsonObject.getInt("code"));
                                errorResponse.setMsg(jsonObject.getString("msg"));
                                mValidationCodeResponse.setValue(errorResponse);
                            } catch (IOException e) {
                                e.printStackTrace();
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }

                @Override
                public void onFailure(Call<DefaultResponse> call, Throwable t) {
                    Log.e(TAG, t.toString());
                    Toast.makeText(getApplication(), R.string.network_error_default,
                            Toast.LENGTH_SHORT).show();
                    if (mValidationCodeResponse != null) {
                        mValidationCodeResponse.setValue(null);
                    }
                }
            });
        }
    }

    public LiveData<LoginResponse> registerResponse() {
        if (mRegisterResponse == null) {
            mRegisterResponse = new MutableLiveData<>();
        }
        return mRegisterResponse;
    }

    public void register(String mobile, String validationCode, RegisterRequest registerRequest) {
        Log.d(TAG, "register");
        final Call<LoginResponse> call = mApiInterface.register(
                mobile + ":" + validationCode, registerRequest);
        if (call != null) {
            call.enqueue(new Callback<LoginResponse>() {
                @Override
                public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
                    Log.d(TAG, "onResponse = " + response);
                    if (response != null && mRegisterResponse != null) {
                        Log.d(TAG, "body " + response.body());
                        if (200 == response.code()) {
                            mRegisterResponse.setValue(response.body());
                        } else {
                            try {
                                String errorString = response.errorBody().string();
                                Log.w(TAG, "error " + errorString);
                                JSONObject jsonObject = new JSONObject(errorString);
                                LoginResponse errorResponse = new LoginResponse();
                                errorResponse.setCode(jsonObject.getInt("code"));
                                errorResponse.setMsg(jsonObject.getString("msg"));
                                mRegisterResponse.setValue(errorResponse);
                            } catch (IOException e) {
                                e.printStackTrace();
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }

                @Override
                public void onFailure(Call<LoginResponse> call, Throwable t) {
                    Log.e(TAG, t.toString());
                    Toast.makeText(getApplication(), R.string.network_error_default,
                            Toast.LENGTH_SHORT).show();
                    if (mRegisterResponse != null) {
                        mRegisterResponse.setValue(null);
                    }
                }
            });
        }
    }

    public LiveData<LoginResponse> loginResponse() {
        if (mLoginResponse == null) {
            mLoginResponse = new MutableLiveData<>();
        }
        return mLoginResponse;
    }

    public void login(LoginRequest loginRequest) {
        Log.d(TAG, "login");
        final Call<LoginResponse> call = mApiInterface.login(loginRequest);
        if (call != null) {
            call.enqueue(new Callback<LoginResponse>() {
                @Override
                public void onResponse(Call<LoginResponse> call, Response<LoginResponse> response) {
                    Log.d(TAG, "onResponse = " + response);
                    if (response != null && mLoginResponse != null) {
                        Log.d(TAG, "body " + response.body());
                        if (200 == response.code()) {
                            mLoginResponse.setValue(response.body());
                        } else {
                            try {
                                String errorString = response.errorBody().string();
                                Log.w(TAG, "error " + errorString);
                                JSONObject jsonObject = new JSONObject(errorString);
                                LoginResponse errorResponse = new LoginResponse();
                                errorResponse.setCode(jsonObject.getInt("code"));
                                errorResponse.setMsg(jsonObject.getString("msg"));
                                mLoginResponse.setValue(errorResponse);
                            } catch (IOException e) {
                                e.printStackTrace();
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }

                @Override
                public void onFailure(Call<LoginResponse> call, Throwable t) {
                    Log.e(TAG, t.toString());
                    Toast.makeText(getApplication(), R.string.network_error_default,
                            Toast.LENGTH_SHORT).show();
                    if (mLoginResponse != null) {
                        mLoginResponse.setValue(null);
                    }
                }
            });
        }
    }

    public LiveData<DefaultResponse> logoutResponse() {
        if (mLogoutResponse == null) {
            mLogoutResponse = new MutableLiveData<>();
        }
        return mLogoutResponse;
    }

    public void logout(String token) {
        Log.d(TAG, "logout");
        final Call<DefaultResponse> call = mApiInterface.logout(token);
        if (call != null) {
            call.enqueue(new Callback<DefaultResponse>() {
                @Override
                public void onResponse(Call<DefaultResponse> call,
                                       Response<DefaultResponse> response) {
                    Log.d(TAG, "onResponse = " + response);
                    if (response != null && mLogoutResponse != null) {
                        Log.d(TAG, "body " + response.body());
                        if (200 == response.code()) {
                            mLogoutResponse.setValue(response.body());
                        } else {
                            try {
                                String errorString = response.errorBody().string();
                                Log.w(TAG, "error " + errorString);
                                JSONObject jsonObject = new JSONObject(errorString);
                                DefaultResponse errorResponse = new DefaultResponse();
                                errorResponse.setCode(jsonObject.getInt("code"));
                                errorResponse.setMsg(jsonObject.getString("msg"));
                                mLogoutResponse.setValue(errorResponse);
                            } catch (IOException e) {
                                e.printStackTrace();
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }

                @Override
                public void onFailure(Call<DefaultResponse> call, Throwable t) {
                    Log.e(TAG, t.toString());
                    Toast.makeText(getApplication(), R.string.network_error_default,
                            Toast.LENGTH_SHORT).show();
                    if (mLogoutResponse != null) {
                        mLogoutResponse.setValue(null);
                    }
                }
            });
        }
    }

    public LiveData<RefreshTokenResponse> reFreshTokenResponse() {
        if (mRefreshTokenResponse == null) {
            mRefreshTokenResponse = new MutableLiveData<>();
        }
        return mRefreshTokenResponse;
    }

    public void refreshToken(String token) {
        Log.d(TAG, "refreshToken");
        final Call<RefreshTokenResponse> call = mApiInterface.refreshToken(token);
        if (call != null) {
            call.enqueue(new Callback<RefreshTokenResponse>() {
                @Override
                public void onResponse(Call<RefreshTokenResponse> call,
                                       Response<RefreshTokenResponse> response) {
                    Log.d(TAG, "onResponse = " + response);
                    if (response != null && mRefreshTokenResponse != null) {
                        Log.d(TAG, "body " + response.body());
                        if (200 == response.code()) {
                            mRefreshTokenResponse.setValue(response.body());
                        } else {
                            try {
                                String errorString = response.errorBody().string();
                                Log.w(TAG, "error " + errorString);
                                JSONObject jsonObject = new JSONObject(errorString);
                                RefreshTokenResponse errorResponse = new RefreshTokenResponse();
                                errorResponse.setCode(jsonObject.getInt("code"));
                                errorResponse.setMsg(jsonObject.getString("msg"));
                                mRefreshTokenResponse.setValue(errorResponse);
                            } catch (IOException e) {
                                e.printStackTrace();
                            } catch (JSONException e) {
                                e.printStackTrace();
                            }
                        }
                    }
                }

                @Override
                public void onFailure(Call<RefreshTokenResponse> call, Throwable t) {
                    Log.e(TAG, t.toString());
                    if (mRefreshTokenResponse != null) {
                        mRefreshTokenResponse.setValue(null);
                    }
                }
            });
        }
    }
}
